<template>
  <div class="app-container" style="height: 100%">
    <div class="app-container-inner" v-loading="loading" element-loading-text="加载中...">
      <div class="header flex-justify-between">
        <div style="display: flex; gap: 5px">
          <HPlainButton @click="addList"> 新增角色 </HPlainButton>
          <el-dropdown trigger="click">
            <HButton :disabled="selecttion.length == 0">
              批量操作
              <el-icon class="el-icon--right">
                <ArrowDown />
              </el-icon>
            </HButton>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="useAll">
                  <el-icon>
                    <CircleCheck />
                  </el-icon>
                  批量启用
                </el-dropdown-item>
                <el-dropdown-item @click="disableAll">
                  <el-icon>
                    <Warning />
                  </el-icon>
                  批量禁用
                </el-dropdown-item>
                <el-dropdown-item @click="deleAll">
                  <el-icon>
                    <Delete />
                  </el-icon>
                  批量删除
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
        <div class="search flex-align-center">
          <el-input
            clearable
            v-model="keyword"
            placeholder="关键词搜索"
            class="input-width"
            @keyup.enter="searchList"
            @clear="searchList"
          >
          </el-input>
          <HButton type="primary" @click="searchList">
            <el-icon>
              <Search />
            </el-icon>
            搜索
          </HButton>
        </div>
      </div>
      <div class="table-role">
        <el-table
          border
          stripe
          resizable
          :data="tableData"
          ref="tableList"
          @selection-change="handleChange"
          height="100%"
          style="position: absolute"
        >
          <!--选择-->
          <el-table-column type="selection" width="40" :selectable="checkDisable" />

          <!--序号-->
          <el-table-column show-overflow-tooltip type="index" label="序号" width="50" />

          <!--角色名称-->
          <el-table-column show-overflow-tooltip prop="name" label="角色名称" min-width="150" />

          <!--角色编码-->
          <el-table-column show-overflow-tooltip prop="code" label="角色编码" width="150" />

          <!--状态-->
          <el-table-column show-overflow-tooltip prop="disabled" label="状态" width="70">
            <template #default="scope">
              <HStatus v-if="!scope.row.status">启用</HStatus>
              <HStatus v-if="scope.row.status" type="info">禁用</HStatus>
            </template>
          </el-table-column>

          <!--创建时间-->
          <el-table-column show-overflow-tooltip prop="updateTime" label="创建时间" width="170" />

          <!--更新时间-->
          <el-table-column show-overflow-tooltip prop="updateTime" label="更新时间" width="170" />

          <!--操作-->
          <el-table-column show-overflow-tooltip fixed="right" label="操作" width="125">
            <template #default="scope">
              <el-space :size="0" :spacer="spacer" v-if="!scope.row.admin">
                <HLink @click="assignAuthor(scope.row)">分配权限</HLink>
                <HLink @click="viewDetail(scope.row)">编辑</HLink>
              </el-space>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="footer">
        <Pagination
          ref="pagination"
          :list_total="total"
          @size-change="getSizeList"
          @current-change="getNumList"
        />
      </div>

      <!-- 编辑角色弹窗 -->
      <HModal v-model="editDialog" :title="roleId ? '编辑角色' : '添加角色'" size="small">
        <div class="form-text" :class="isAdmin == true ? '' : 'mb10'">
          <el-form
            label-width="80"
            ref="ruleFormRef"
            :rules="rules"
            :model="ruleForm"
            class="modal_form_content"
            @validate="handleFormValidate"
          >
            <!-- 角色名称 -->
            <el-form-item
              label="角色名称"
              class="form_input_item"
              :class="{ error_form_item: !formValidateResult['name'] }"
              prop="name"
            >
              <el-input
                clearable
                v-model="ruleForm.name"
                :disabled="isAdmin == true"
                placeholder="请输入名称"
              />
            </el-form-item>

            <!-- 角色编码 -->
            <el-form-item
              label="角色编码"
              class="form_input_item"
              :class="{ error_form_item: !formValidateResult['code'] }"
              prop="code"
            >
              <el-input
                clearable
                v-model="ruleForm.code"
                :disabled="isAdmin == true"
                placeholder="请输入编码"
              />
            </el-form-item>

            <!-- 角色状态 -->
            <el-form-item
              label="角色状态"
              class="form_radio_group_item"
              :class="isAdmin == true ? '' : 'form-item'"
            >
              <el-radio-group v-model="status">
                <el-radio :value="false" :disabled="isAdmin == true">
                  <span class="bg_text">启用</span>
                </el-radio>
                <el-radio :value="true" :disabled="isAdmin == true">
                  <span class="bg_text">禁用</span>
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </el-form>
        </div>

        <template #footerLeft>
          <HPlainBgButton is-modal type="error" v-if="roleId" @click="deleteRole"
            >删除</HPlainBgButton
          >
        </template>

        <template #footerRight>
          <HButton is-modal type="primary" @click="submitForm(ruleFormRef)">保存</HButton>
          <HButton is-modal @click="onAddOrEditRoleModalClose">取消</HButton>
        </template>
      </HModal>

      <!-- 分配角色权限弹窗 -->
      <HModal v-model="assignDialog" :title="`分配【${ruleForm.name}】权限`" :width="750">
        <el-checkbox
          :indeterminate="isIndeterminate"
          v-model="allValue"
          @change="changeAll"
          size="large"
          name="type"
        >
          全选
        </el-checkbox>
        <el-cascader-panel
          :props="optionProps"
          @change="changeValue"
          v-if="roleAuthorVos"
          v-model="roleAuthorVos"
          :options="getAllAuthorList"
        />
        <template #footerRight>
          <HButton is-modal type="primary" v-if="!isAdmin" @click="saveRoleAuthorVo">保存</HButton>
          <HButton is-modal @click="assignDialog = false">取消</HButton>
        </template>
      </HModal>
    </div>
  </div>
</template>

<script setup lang="ts">
  import Pagination from '@/components/Pagination/index.vue'
  import { Search, Delete, Warning, CircleCheck, ArrowDown } from '@element-plus/icons-vue'
  import { ref, onMounted, markRaw, reactive, h } from 'vue'
  import { ElDivider, ElMessage, ElMessageBox } from 'element-plus'
  import type { FormInstance } from 'element-plus'
  import {
    getRoleList,
    changeRole,
    deleRole,
    saveRole,
    getAllAuthor,
    getRoleAuthor,
    saveRoleAuthor,
  } from '@/api/role'
  import HPlainButton from '@/components/common/button/HPlainButton.vue'
  import HButton from '@/components/common/button/HButton.vue'
  import HPlainBgButton from '@/components/common/button/HPlainBgButton.vue'
  import HStatus from '@/components/common/status/HStatus.vue'
  import HLink from '@/components/common/link/HLink.vue'
  import HModal from '@/components/common/Modal/HModal.vue'
  import useFormValidateService from '@/service/common/useFormValidate/useFormValidateService'
  import pageComponentName from '@/config/page-component-name'

  defineOptions({
    name: pageComponentName.accountPermission.rolePermission,
  })

  /**
   * 使用表单验证服务
   */
  const { handleFormValidate, resetFormValidateResult, formValidateResult } =
    useFormValidateService([
      { name: 'name', isSelect: false },
      { name: 'code', isSelect: false },
    ])

  /**
   * 编辑/添加角色弹窗关闭事件
   */
  const onAddOrEditRoleModalClose = () => {
    editDialog.value = false
    resetFormValidateResult()
  }

  // 间距组件的间隔符
  const spacer = h(ElDivider, {
    direction: 'vertical',
    style: 'display: flex; align-items: center;',
  })

  const loading = ref(false)
  const editDialog = ref(false)
  const assignDialog = ref(false)
  const tableData = ref([]) // 角色列表
  const total = ref() // 总数量
  const limit = ref() // 每页显示数量
  const page = ref() // 当面页码
  const keyword = ref('') // 搜索关键词
  const pagination = ref() // 分页dom
  const tableList = ref() // 列表dom

  const roleId = ref('') // 角色ID
  const authorIds = ref([]) // 权限ID集合
  const empIds = ref([]) // 角色账号ID集合
  const status = ref(false) // 角色状态 false-正常，true-禁用

  const isAdmin = ref(false) // 是否是超管

  // const allId
  const isIndeterminate = ref(true)
  const allValue = ref(false)
  const checkAllIds = ref([]) //全选的ids
  const changeAll = (val) => {
    if (val) {
      roleAuthorVos.value = checkAllIds.value
    } else {
      roleAuthorVos.value = []
    }
    isIndeterminate.value = false
  }
  const changeValue = () => {
    let array1 = []
    let array2 = []
    for (let i = 0; i < roleAuthorVos.value.length; i++) {
      let item = roleAuthorVos.value[i]
      array1.push(...item)
    }
    for (let i = 0; i < checkAllIds.value.length; i++) {
      let item = checkAllIds.value[i]
      array2.push(...item)
    }
    if (arraysAreEqual(array1, array2) && roleAuthorVos.value.length > 0) {
      allValue.value = true
    } else {
      allValue.value = false
    }
    isIndeterminate.value = roleAuthorVos.value.length > 0 && !arraysAreEqual(array1, array2)
  }
  // 将两个数组排序判断是否相等
  function arraysAreEqual(arr1, arr2) {
    if (arr1.length !== arr2.length) {
      return false
    }
    const sortedArr1 = arr1.slice().sort()
    const sortedArr2 = arr2.slice().sort()
    for (let i = 0; i < sortedArr1.length; i++) {
      if (sortedArr1[i] !== sortedArr2[i]) {
        return false
      }
    }
    return true
  }

  // 表单数据
  const ruleForm = reactive({
    name: '', // 角色名称
    code: '', // 角色编码
  })

  const getAllAuthorList = ref() //权限列表
  const roleAuthorVos = ref([]) //绑定选中的
  const optionProps = ref({
    multiple: true, //是否多选
    value: 'authorId',
    label: 'name',
    children: 'authorVos',
  })
  // 表单元素
  const ruleFormRef = ref<FormInstance>()

  // 验证规则
  const rules = reactive({
    name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
    code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }],
  })

  // 获取角色列表
  const getList = async () => {
    loading.value = true
    limit.value = pagination.value.size
    page.value = pagination.value.current
    const data = {
      keyword: keyword.value,
      limit: limit.value,
      page: page.value,
    }
    await getRoleList(data).then((res) => {
      total.value = parseInt(res.data.data.total)
      loading.value = false
      tableData.value = res.data.data.rows
    })
  }
  // *****************获取权限列表**********
  const AllAuthorList = async () => {
    await getAllAuthor().then((res) => {
      if (res) {
        getAllAuthorList.value = res.data.data.rows
        checkAllIds.value = getIds(res.data.data.rows)
      }
    })
  }
  // *****************end*****************
  // ***********根据角色ID获取角色权限***********
  const getRoleAuthorItem = async (id) => {
    roleAuthorVos.value = []
    loading.value = true
    await getRoleAuthor(id).then((res) => {
      if (res.data) {
        roleAuthorVos.value = getIds(res.data.data.rows)
        AllAuthorList()
        changeValue()
      }
    })
    loading.value = false
  }
  function getIds(arr) {
    let result = []
    arr.forEach((obj) => {
      let id = obj.authorId
      if (obj.authorVos.length > 0) {
        let subArr = getIds(obj.authorVos)
        subArr.forEach((subIds) => {
          result.push([id, ...subIds])
        })
      } else {
        result.push([id])
      }
    })
    return result
  }
  // ****************end**************
  // 分配权限
  const assignAuthor = async (obj) => {
    roleAuthorVos.value = []
    roleId.value = obj.id
    isAdmin.value = obj.admin
    ruleForm.name = obj.name
    await getRoleAuthorItem(roleId.value)
    assignDialog.value = true
  }
  // 处理选择的数据
  function transformArray(arr) {
    const result = []
    arr.forEach((subArr) => {
      let current = result
      subArr.forEach((authorId, index) => {
        let found = current.find((item) => item.authorId === authorId)
        if (!found) {
          found = { authorId: authorId, authorVos: [] }
          current.push(found)
        }
        if (index === subArr.length - 1) {
          found.authorVos = []
        } else {
          current = found.authorVos
        }
      })
    })
    return result
  }

  // 保存分配权限
  const saveRoleAuthorVo = () => {
    let data = []
    data = transformArray(roleAuthorVos.value)
    saveRoleAuthor(data, roleId.value).then((res) => {
      if (res.data.success == true) {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 2000,
        })
        assignDialog.value = false
      } else {
        if (res.data.isError)
          ElMessage({
            message: res.data.message,
            type: 'warning',
            duration: 2000,
          })
      }
    })
  }
  onMounted(() => {
    getList()
  })

  // 获取表格选中的数据
  const selecttion = ref([])
  const handleChange = (val) => {
    if (val.length != 0) {
      val.forEach((item) => {
        if (selecttion.value.indexOf(item.id) == -1) {
          selecttion.value.push(item.id)
        } else {
          selecttion.value = selecttion.value.filter((i) => i == item.id)
        }
      })
    } else {
      selecttion.value = []
    }
  }

  // 判断是否可选
  const checkDisable = (row) => {
    if (row.admin == true) {
      return false // 可选
    } else {
      return true // 不可选
    }
  }

  // 添加角色
  const addList = () => {
    ruleForm.name = ''
    ruleForm.code = ''
    status.value = false
    roleId.value = ''
    isAdmin.value = false
    editDialog.value = true
  }

  // 保存角色
  const submitForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.validate(async (valid) => {
      if (valid) {
        const data = {
          authorIds: authorIds.value,
          code: ruleForm.code,
          empIds: empIds.value,
          name: ruleForm.name,
          status: status.value,
        }
        const data2 = {
          authorIds: authorIds.value,
          code: ruleForm.code,
          empIds: empIds.value,
          id: roleId.value,
          name: ruleForm.name,
          status: status.value,
        }
        if (roleId.value == '') {
          // 新增
          await saveRole(data).then((res) => {
            if (res.data.success == true) {
              ElMessage({
                message: res.data.message,
                type: 'success',
                duration: 2000,
              })
              editDialog.value = false
              getList()
            } else {
              if (res.data.isError)
                ElMessage({
                  message: res.data.message,
                  type: 'warning',
                  duration: 2000,
                })
              return
            }
          })
        } else {
          // 编辑
          await saveRole(data2).then((res) => {
            if (res.data.success == true) {
              ElMessage({
                message: res.data.message,
                type: 'success',
                duration: 2000,
              })
              editDialog.value = false
              getList()
            } else {
              if (res.data.isError)
                ElMessage({
                  message: res.data.message,
                  type: 'warning',
                  duration: 2000,
                })
              return
            }
          })
        }
      } else {
        return
      }
    })
  }

  // 删除角色
  const deleteRole = () => {
    let tmp = []
    tmp.push(roleId.value)
    ElMessageBox({
      type: 'error',
      icon: markRaw(Delete),
      title: '提示',
      message: '确认删除该角色?',
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    }).then(async () => {
      await deleRole(tmp).then((res) => {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 2000,
        })
      })
      selecttion.value = []
      editDialog.value = false
      tableList.value.clearSelection()
      getList()
    })
  }

  // 查看角色详细
  const viewDetail = (obj) => {
    roleId.value = obj.id
    isAdmin.value = obj.admin
    ruleForm.name = obj.name
    ruleForm.code = obj.code
    status.value = obj.status
    editDialog.value = true
  }

  // 搜索角色
  const searchList = () => {
    keyword.value = ''
    getList()
  }

  // 显示数量改变时
  const getSizeList = () => {
    getList()
  }

  // 页码改变时
  const getNumList = () => {
    getList()
  }

  // 批量启用
  const useAll = () => {
    if (selecttion.value.length == 0) {
      ElMessage({
        message: '请选择要启用的角色',
        type: 'warning',
        duration: 2000,
      })
      return
    }
    ElMessageBox({
      title: '提示',
      message: '确认启用选中的角色?',
      type: 'warning',
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    }).then(async () => {
      await changeRole(selecttion.value, { status: status.value }).then((res) => {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 2000,
        })
      })
      selecttion.value = []
      tableList.value.clearSelection()
      getList()
    })
  }

  // 批量禁用
  const disableAll = () => {
    if (selecttion.value.length == 0) {
      ElMessage({
        message: '请选择要禁用的角色',
        type: 'warning',
        duration: 2000,
      })
      return
    }
    ElMessageBox({
      type: 'warning',
      title: '提示',
      message: '确认禁用选中的角色?',
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    }).then(async () => {
      await changeRole(selecttion.value, { status: !status.value }).then((res) => {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 2000,
        })
      })
      selecttion.value = []
      tableList.value.clearSelection()
      getList()
    })
  }

  // 批量删除
  const deleAll = () => {
    if (selecttion.value.length == 0) {
      ElMessage({
        message: '请选择要删除的角色',
        type: 'warning',
        duration: 2000,
      })
      return
    }
    ElMessageBox({
      type: 'error',
      title: '提示',
      message: '确认删除选中的角色?',
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    }).then(async () => {
      loading.value = true
      await deleRole(selecttion.value).then((res) => {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 2000,
        })
      })
      selecttion.value = []
      tableList.value.clearSelection()
      getList()
    })
  }
</script>

<style scoped lang="scss">
  @import './index';
</style>
